package com.ruoyi.project.system.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.*;
import com.ruoyi.project.system.mapper.BrandMapper;
import com.ruoyi.project.system.mapper.TypeMapper;
import com.ruoyi.project.system.service.*;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.mapper.OrderDetailsMapper;

/**
 * 订单详情Service业务层处理
 *
 * @author tsxuwj
 * @date 2020-06-22
 */
@Service
public class OrderDetailsServiceImpl implements IOrderDetailsService {
    @Autowired
    private OrderDetailsMapper orderDetailsMapper;
    @Autowired
    private IEquipmentService equipmentService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IClientService clientService;
    @Autowired
    private TypeMapper typeMapper;
    @Autowired
    private BrandMapper brandMapper;

    /**
     * 查询订单详情
     *
     * @param id 订单详情ID
     * @return 订单详情
     */
    @Override
    public OrderDetails selectOrderDetailsById(Long id) {
        return orderDetailsMapper.selectOrderDetailsById(id);
    }

    /**
     * 查询订单详情列表
     *
     * @param orderDetails 订单详情
     * @return 订单详情
     */
    @Override
    public List<OrderDetails> selectOrderDetailsList(OrderDetails orderDetails) {
        return orderDetailsMapper.selectOrderDetailsList(orderDetails);
    }

    /**
     * 新增订单详情
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    @Override
    public int insertOrderDetails(OrderDetails orderDetails) {
        return orderDetailsMapper.insertOrderDetails(orderDetails);
    }

    /**
     * 修改订单详情
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    @Override
    public int updateOrderDetails(OrderDetails orderDetails) {
        return orderDetailsMapper.updateOrderDetails(orderDetails);
    }

    /**
     * 批量删除订单详情
     *
     * @param ids 需要删除的订单详情ID
     * @return 结果
     */
    @Override
    public int deleteOrderDetailsByIds(Long[] ids) {
        return orderDetailsMapper.deleteOrderDetailsByIds(ids);
    }

    /**
     * 删除订单详情信息
     *
     * @param id 订单详情ID
     * @return 结果
     */
    @Override
    public int deleteOrderDetailsById(Long id) {
        return orderDetailsMapper.deleteOrderDetailsById(id);
    }

    /**
     * 新增订单详情-自写
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    @Override
    public int insertOrderDetailsTSXUWJ(OrderDetails orderDetails) {
        Equipment equipment = equipmentService.selectEquipmentById(orderDetails.getEquipmentId());
        orderDetails.setPrice(equipment.getPrice());
        orderDetails.setPriceCost(equipment.getCostPrice());
        orderDetails.setPriceTotalCost(equipment.getCostPrice().multiply(new BigDecimal(orderDetails.getCount().toString())));
        orderDetails.setPriceTotal(equipment.getPrice().multiply(new BigDecimal(orderDetails.getCount().toString())));
        orderDetailsMapper.insertOrderDetails(orderDetails);
        return addOrderPrice(orderDetails);
    }

    /**
     * 修改订单详情-自写
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    @Override
    public int updateOrderDetailsTSXUWJ(OrderDetails orderDetails) {
        return updateOrderPrice(orderDetails);
    }

    /**
     * 删除订单详情信息-自写
     *
     * @param id 订单详情ID
     * @return 结果
     */
    @Override
    public int deleteOrderDetailsByIdTSXUWJ(Long id) {
        OrderDetails orderDetails = orderDetailsMapper.selectOrderDetailsById(id);
        Order order = orderService.selectOrderById(orderDetails.getOrderId());
        order.setEquipmentPrice(order.getEquipmentPrice().subtract(orderDetails.getPriceTotal()));
        order.setEquipmentPriceCost(order.getEquipmentPriceCost().subtract(orderDetails.getPriceTotalCost()));
        BigDecimal equipmentPrice = order.getEquipmentPrice().multiply(new BigDecimal(String.valueOf(order.getProduct() / 100.0)));
        BigDecimal constructionPrice = order.getConstructionPrice().multiply(new BigDecimal(String.valueOf(order.getLabor() / 100.0)));
        order.setTaxation(equipmentPrice.add(constructionPrice));
        order.setPrice(order.getEquipmentPrice().add(order.getConstructionPrice().add(order.getTaxation())));
        order.setPriceCost(order.getEquipmentPriceCost().add(order.getConstructionPriceCost().add(order.getTaxation())));
        orderDetailsMapper.deleteOrderDetailsById(id);
        return orderService.updateOrder(order);
    }

    /**
     * 查询订单详情列表-自写
     *
     * @param orderDetails 订单详情
     * @return 订单详情集合
     */
    @Override
    public List<OrderDetails> selectOrderDetailsListTSXUWJ(OrderDetails orderDetails) {
        return orderDetailsMapper.selectOrderDetailsListTSXUWJ(orderDetails);
    }

    /**
     * 导出订单详情-自写
     *
     * @param orderDetails 订单详情
     * @return 订单详情集合
     */
    @Override
    public AjaxResult exportOrderDetailsTSXUWJ(OrderDetails orderDetails) throws IOException {
        List<OrderDetails> orderDetailsList = orderDetailsMapper.selectOrderDetailsListTSXUWJ(orderDetails);
        Order order = orderService.selectOrderById(orderDetails.getOrderId());
        Client client = clientService.selectClientById(order.getClientId());
        List<Type> types = typeMapper.selectTypeList(new Type());
        List<Brand> brands = brandMapper.selectBrandList(new Brand());

        XSSFWorkbook workbook = new XSSFWorkbook();//创建Excel文件(Workbook)
        XSSFSheet sheet = workbook.createSheet("Test");// 创建工作表(Sheet)
        XSSFCellStyle cellStyleAlignmentBorder = workbook.createCellStyle();//剧中+边框样式
        cellStyleAlignmentBorder.setAlignment(HorizontalAlignment.CENTER);//剧中
        cellStyleAlignmentBorder.setBorderTop(BorderStyle.THIN);
        cellStyleAlignmentBorder.setBorderRight(BorderStyle.THIN);
        cellStyleAlignmentBorder.setBorderBottom(BorderStyle.THIN);
        cellStyleAlignmentBorder.setBorderLeft(BorderStyle.THIN);
        XSSFCellStyle cellStyleAlignmentBorderRed = workbook.createCellStyle();//添加红色字体
        cellStyleAlignmentBorderRed.cloneStyleFrom(cellStyleAlignmentBorder);
        XSSFFont font = workbook.createFont();
        font.setColor(Font.COLOR_RED);
        cellStyleAlignmentBorderRed.setFont(font);
        XSSFCellStyle cellStyleAlignmentBorderMoney = workbook.createCellStyle();//添加货币格式
        cellStyleAlignmentBorderMoney.cloneStyleFrom(cellStyleAlignmentBorder);
        DataFormat dataFormat = workbook.createDataFormat();
        cellStyleAlignmentBorderMoney.setDataFormat(dataFormat.getFormat("¥#,##0.00"));

        XSSFRow row = sheet.createRow(0);// 创建行,从0开始
        row.createCell(3).setCellValue("客户名称：");// 设置单元格内容
        row.createCell(4).setCellValue(client.getName() + "公司");
        row = sheet.createRow(1);
        row.createCell(3).setCellValue("项目名称：");// 设置单元格内容
        row.createCell(4).setCellValue(order.getName() + "项目");
        row = sheet.createRow(2);
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter formatDataTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        XSSFCell cell = row.createCell(0);
        cell.setCellValue("报价生成时间：" + localDateTime.format(formatDataTime));
        cell.setCellStyle(cellStyleAlignmentBorder);
        CellRangeAddress cellRangeAddress = new CellRangeAddress(2, 2, 0, 11);
        sheet.addMergedRegion(cellRangeAddress);//合并单元格
        RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet);

        row = sheet.createRow(3);
        String[] title = {"序号", "名称", "品牌", "型号", "参数", "数量", "单位", "单价", "成本单价", "成本小计", "合计", "备注"};
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(cellStyleAlignmentBorder);
        }
        Map<Long, List<OrderDetails>> collect = orderDetailsList.stream().collect(Collectors.groupingBy((od) -> {
            return od.getEquipment().getTypeId();
        }));

        int num = 1, rowNum = 4;
        for (Map.Entry<Long, List<OrderDetails>> entry : collect.entrySet()) {
            Long k = entry.getKey();
            List<OrderDetails> v = entry.getValue();
            row = sheet.createRow(rowNum++);
            cell = row.createCell(0);//序号
            cell.setCellStyle(cellStyleAlignmentBorder);
            cell.setCellValue(num++);
            cell = row.createCell(1);//名称
            cell.setCellStyle(cellStyleAlignmentBorderRed);
            for (Type type : types) {
                if (type.getId().toString().equals(k.toString())) {
                    cell.setCellValue(type.getName());
                    break;
                }
            }
            for (int i = 2; i < 12; i++) {
                cell = row.createCell(i);//填充边框
                cell.setCellStyle(cellStyleAlignmentBorder);
            }
            for (OrderDetails details : v) {
                row = sheet.createRow(rowNum++);
                cell = row.createCell(0);//序号
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(num++);
                cell = row.createCell(1);//名称
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getEquipment().getName());
                cell = row.createCell(2);//品牌
                cell.setCellStyle(cellStyleAlignmentBorder);
                for (Brand brand : brands) {
                    if (brand.getId().toString().equals(details.getEquipment().getBrandId().toString())) {
                        cell.setCellValue(brand.getName());
                        break;
                    }
                }
                cell = row.createCell(3);//型号
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getEquipment().getModel());
                cell = row.createCell(4);//参数
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getEquipment().getParameter());
                cell = row.createCell(5);//数量
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getCount());
                cell = row.createCell(6);//单位
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getEquipment().getUnits());
                cell = row.createCell(7);//单价
                cell.setCellStyle(cellStyleAlignmentBorderMoney);
                cell.setCellValue(Double.parseDouble(details.getPrice().toString()));
                cell = row.createCell(8);//成本单价
                cell.setCellStyle(cellStyleAlignmentBorderMoney);
                cell.setCellValue(Double.parseDouble(details.getPriceCost().toString()));
                cell = row.createCell(9);//成本小计
                cell.setCellStyle(cellStyleAlignmentBorderMoney);
                cell.setCellValue(Double.parseDouble(details.getPriceTotalCost().toString()));
                cell = row.createCell(10);//合计
                cell.setCellStyle(cellStyleAlignmentBorderMoney);
                cell.setCellValue(Double.parseDouble(details.getPriceTotal().toString()));
                cell = row.createCell(11);//备注
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell.setCellValue(details.getRemark());
            }
        }

        String[] name = {"设备合计", "施工费", "税费", "总投资合计"};
        for (String s : name) {
            row = sheet.createRow(rowNum);
            cell = row.createCell(0);
            cell.setCellValue(num);// 序号
            cell.setCellStyle(cellStyleAlignmentBorder);
            cell = row.createCell(1);
            cell.setCellValue(s);// 名称
            cell.setCellStyle(cellStyleAlignmentBorder);
            XSSFCell cell9 = row.createCell(9);
            cell9.setCellStyle(cellStyleAlignmentBorderMoney);
            XSSFCell cell10 = row.createCell(10);
            cell10.setCellStyle(cellStyleAlignmentBorderMoney);
            cell = row.createCell(11);//备注
            cell.setCellStyle(cellStyleAlignmentBorder);
            if (s.equals("设备合计")) {
                cell9.setCellValue(Double.parseDouble(order.getEquipmentPriceCost().toString()));// 成本小计
                cell10.setCellValue(Double.parseDouble(order.getEquipmentPrice().toString()));// 合计
            } else if (s.equals("施工费")) {
                cell9.setCellValue(Double.parseDouble(order.getConstructionPriceCost().toString()));// 成本小计
                cell10.setCellValue(Double.parseDouble(order.getConstructionPrice().toString()));// 合计
            } else if (s.equals("税费")) {
                cell = row.createCell(2);
                cell.setCellValue("人工费" + order.getLabor() + "%+产品" + order.getProduct() + "%");
                cell.setCellStyle(cellStyleAlignmentBorder);
                cell9.setCellValue(Double.parseDouble(order.getTaxation().toString()));// 成本小计
                cell10.setCellValue(Double.parseDouble(order.getTaxation().toString()));// 合计
            } else if (s.equals("总投资合计")) {
                cell9.setCellValue(Double.parseDouble(order.getPriceCost().toString()));// 成本小计
                cell10.setCellValue(Double.parseDouble(order.getPrice().toString()));// 合计
            }
            cellRangeAddress = new CellRangeAddress(rowNum, rowNum, 2, 8);
            sheet.addMergedRegion(cellRangeAddress);//合并单元格
            RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet);
            RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet);
            RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet);
            RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet);
            rowNum++;
            num++;
        }
        sheet.autoSizeColumn(7);
        sheet.autoSizeColumn(8);
        sheet.autoSizeColumn(9);
        sheet.autoSizeColumn(10);

        OutputStream out = new FileOutputStream(getAbsoluteFile("details.xlsx"));
        workbook.write(out);
        out.close();
        return AjaxResult.success("details.xlsx");
    }

    /**
     * 添加设备时计算总价格-自写
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    private int addOrderPrice(OrderDetails orderDetails) {
        Order order = orderService.selectOrderById(orderDetails.getOrderId());
        order.setEquipmentPrice(order.getEquipmentPrice().add(orderDetails.getPriceTotal()));
        order.setEquipmentPriceCost(order.getEquipmentPriceCost().add(orderDetails.getPriceTotalCost()));
        BigDecimal equipmentPrice = order.getEquipmentPrice().multiply(new BigDecimal(String.valueOf(order.getProduct() / 100.0)));
        BigDecimal constructionPrice = order.getConstructionPrice().multiply(new BigDecimal(String.valueOf(order.getLabor() / 100.0)));
        order.setTaxation(equipmentPrice.add(constructionPrice));
        order.setPrice(order.getEquipmentPrice().add(order.getConstructionPrice().add(order.getTaxation())));
        order.setPriceCost(order.getEquipmentPriceCost().add(order.getConstructionPriceCost().add(order.getTaxation())));
        return orderService.updateOrder(order);
    }

    /**
     * 更新设备时计算总价格-自写
     *
     * @param orderDetails 订单详情
     * @return 结果
     */
    private int updateOrderPrice(OrderDetails orderDetails) {
        OrderDetails od = orderDetailsMapper.selectOrderDetailsById(orderDetails.getId());
        long count = orderDetails.getCount() - od.getCount();
        orderDetails.setPriceTotal(od.getPriceTotal().add(new BigDecimal(String.valueOf(od.getPrice().multiply(new BigDecimal(String.valueOf(count)))))));
        orderDetails.setPriceTotalCost(od.getPriceTotalCost().add(new BigDecimal(String.valueOf(od.getPriceCost().multiply(new BigDecimal(String.valueOf(count)))))));
        orderDetailsMapper.updateOrderDetails(orderDetails);
        Order order = orderService.selectOrderById(orderDetails.getOrderId());
        order.setEquipmentPrice(order.getEquipmentPrice().add(new BigDecimal(String.valueOf(od.getPrice().multiply(new BigDecimal(String.valueOf(count)))))));
        order.setEquipmentPriceCost(order.getEquipmentPriceCost().add(new BigDecimal(String.valueOf(od.getPriceCost().multiply(new BigDecimal(String.valueOf(count)))))));
        BigDecimal equipmentPrice = order.getEquipmentPrice().multiply(new BigDecimal(String.valueOf(order.getProduct() / 100.0)));
        BigDecimal constructionPrice = order.getConstructionPrice().multiply(new BigDecimal(String.valueOf(order.getLabor() / 100.0)));
        order.setTaxation(equipmentPrice.add(constructionPrice));
        order.setPrice(order.getEquipmentPrice().add(order.getConstructionPrice().add(order.getTaxation())));
        order.setPriceCost(order.getEquipmentPriceCost().add(order.getConstructionPriceCost().add(order.getTaxation())));
        return orderService.updateOrder(order);
    }

    /**
     * 获取下载路径-自写
     *
     * @param filename 文件名称
     */
    private String getAbsoluteFile(String filename) {
        String downloadPath = RuoYiConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }

}
